package cn.edu.tju.scs.network.ftp.server;

import cn.edu.tju.scs.network.ftp.utils.CmdEnum;
import cn.edu.tju.scs.network.ftp.utils.CommandLine;
import cn.edu.tju.scs.network.ftp.utils.UserProfile;

import java.io.*;
import java.net.Socket;

class Transferfile extends Thread {
    Socket ClientSoc;

    DataInputStream din;
    DataOutputStream dout;
    private ThreadLocal<UserProfile> userProfile;

    Transferfile(Socket soc) {
        try {
            ClientSoc = soc;
            din = new DataInputStream(ClientSoc.getInputStream());
            dout = new DataOutputStream(ClientSoc.getOutputStream());
            System.out.println("FTP Client Connected ...");
            start();

        } catch (Exception ex) {
        }
    }

    void SendFile(CommandLine commandLine, ThreadLocal<UserProfile> userProfile) throws Exception {
        // 取出文件名

        String filename = commandLine.args[0];
        File f = new File(userProfile.get().getCurPath() + File.separator + filename);
        if (!f.exists()) {
            dout.writeUTF("File Not Found");
            return;
        } else {
            dout.writeUTF("READY");
            // 检测是否重复
            if (din.readUTF().equals("File already exists") && din.readUTF().equals("N")) {
                return;
            }
            FileInputStream fin = new FileInputStream(f);
            int ch;
            do {
                ch = fin.read();
                dout.writeUTF(String.valueOf(ch));
            } while (ch != -1);
            fin.close();
//            dout.writeUTF("File Receive Successfully");
        }
    }

    void ReceiveFile(CommandLine commandLine, ThreadLocal<UserProfile> userProfile) throws Exception {
        if (commandLine.args == null || commandLine.args.length == 0) {
            System.out.println("参数错误");
            return;
        }

        if (din.readUTF().equals("File not exists")) {
            return;
        }
        // 取出文件名
        String[] strs = commandLine.args[0].split(File.separator);

        String filename = strs[strs.length - 1];
        File f = new File(userProfile.get().getCurPath() + File.separator + filename);
        String option;


        if (f.exists()) {
            dout.writeUTF("File Already Exists");
            option = din.readUTF();
        } else {
            dout.writeUTF("SendFile");
            option = "Y";
            f.createNewFile();
        }

        if (option.compareTo("Y") == 0) {
            FileOutputStream fout = new FileOutputStream(f);
            int ch;
            String temp;
            do {
                temp = din.readUTF();
                ch = Integer.parseInt(temp);
                if (ch != -1) {
                    fout.write(ch);
                }
            } while (ch != -1);
            fout.close();
//            dout.writeUTF("File Send Successfully");
        } else {
            return;
        }

    }

    void CDInstruction(String path) throws Exception {
        File file = new File(userProfile.get().getCurPath() + File.separator + path);
        if (!file.exists() && !file.isDirectory()) {
            System.out.println("目录不存在！");
            dout.writeUTF("Directory not found");
        } else {
            userProfile.get().setCurPath(file.getCanonicalPath());
            dout.writeUTF("Directory found");
            dout.writeUTF(file.getCanonicalPath());
        }
    }

    void LSInstruction() throws Exception {
        File file = new File(userProfile.get().getCurPath());
        String fileList[] = file.list();
        String filename = "";
        for (int i = 0; i < fileList.length; i++) {
            filename += fileList[i];
            if (i == fileList.length - 1) {
                //filename += "\n";
            } else {
                filename += " ";
            }
        }
        dout.writeUTF(filename);
        System.out.println(filename);
    }

    void MKDIRInstruction(String dir) throws Exception {
        File file = new File(userProfile.get().getCurPath() + File.separator + dir);
        if (file.exists() && file.isDirectory()) {
            dout.writeUTF("Mkdir failed");
            System.out.println("创建失败，文件夹已存在");
        } else {
            file.mkdirs();
            dout.writeUTF("Mkdir success");
            System.out.println("文件夹创建成功");
        }
    }

    void PWDInstruction() throws Exception {
        String path = new File(userProfile.get().getCurPath()).getCanonicalPath();
        dout.writeUTF(path);
        System.out.println("当前路径为：" + path);
    }

    void RMDIRInstruction(String dir) throws Exception {
        File file = new File(userProfile.get().getCurPath() + File.separator + dir);
        if (!deleteDirectory(userProfile.get().getCurPath() + File.separator + dir)) {
            dout.writeUTF("Rmdir failed");
            System.out.println("文件夹删除失败");
        } else {
            dout.writeUTF("Rmdir success");
            System.out.println("文件夹删除成功");
        }
    }

    /**
     * 删除目录（文件夹）以及目录下的文件
     *
     * @param sPath 被删除目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public boolean deleteDirectory(String sPath) {
        //如果sPath不以文件分隔符结尾，自动添加文件分隔符
        if (!sPath.endsWith(File.separator)) {
            sPath = sPath + File.separator;
        }
        File dirFile = new File(sPath);
        //如果dir对应的文件不存在，或者不是一个目录，则退出
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        Boolean flag = true;
        //删除文件夹下的所有文件(包括子目录)
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            //删除子文件
            if (files[i].isFile()) {
                flag = files[i].delete();
                if (!flag) break;
            } //删除子目录
            else {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) break;
            }
        }
        if (!flag) return false;
        //删除当前目录
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }

    private void DELETEInstruction(String dir) throws Exception {
        File file = new File(userProfile.get().getCurPath() + File.separator + dir);
        if (!file.delete()) {
            dout.writeUTF("delete failed");
            System.out.println("文件删除失败");
        } else {
            dout.writeUTF("delete success");
            System.out.println("文件删除成功");
        }

    }


    public void run() {
        userProfile = new ThreadLocal<UserProfile>();
        userProfile.set(new UserProfile("1", "1"));
        new File(userProfile.get().getCurPath()).mkdirs();
        while (true) {
            try {
                System.out.println("Waiting for Command ...");
                CommandLine commandLine = CommandLine.buildFromLine(din.readUTF());
                System.out.println("cmd line : " + commandLine.source);

                if (commandLine.isCmd(CmdEnum.CD)) {
                    //将路径传给后台,并处理返回 eg: Request:cd user  Response: user doesn't exist | NONE
                    if(commandLine.args == null){
                        continue;
                    }
                    CDInstruction(commandLine.args[0]);
                } else if (commandLine.isCmd(CmdEnum.DELETE)) {
                    // 将路径传给后台,并处理返回 eg: Request:delete file.txt  Response: file.txt doesn't exist | OK
                    if(commandLine.args == null){
                        continue;
                    }
                    DELETEInstruction(commandLine.args[0]);
                } else if (commandLine.isCmd(CmdEnum.LS)) {
                    //显示目录和文件名 eg: Request:ls  Response: user test (各种文件名)
                    LSInstruction();
                } else if (commandLine.isCmd(CmdEnum.MKDIR)) {
                    //创建目录 eg: Request:mkdir test  Response: test already exist | OK
                    if(commandLine.args == null){
                        continue;
                    }
                    MKDIRInstruction(commandLine.args[0]);
                } else if (commandLine.isCmd(CmdEnum.PWD)) {
                    //显示user当前目录 eg: Request:pwd  Response: /User/local/test
                    PWDInstruction();
                } else if (commandLine.isCmd(CmdEnum.RMDIR)) {
                    //删除目录 eg: Request:rmdir test  Response: test doesn't exist | OK
                    if(commandLine.args == null){
                        continue;
                    }
                    RMDIRInstruction(commandLine.args[0]);
                } else if (commandLine.isCmd(CmdEnum.GET)) {
                    SendFile(commandLine, userProfile);
                } else if (commandLine.isCmd(CmdEnum.SEND)) {
                    ReceiveFile(commandLine, userProfile);
                } else if (commandLine.isCmd(CmdEnum.BYE)) {
                    break;
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }


}